﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Speech.Synthesis;
using System.Threading;

namespace osu_BeatmapAutoLoader
{
    public delegate void DownloadStartEventHandler(string setId, string fileName);

    internal static class DownloadManagement
    {
        private static readonly Dictionary<string, Thread> dic_thread = new Dictionary<string, Thread>();

        public static void Run()
        {
            var synth = new SpeechSynthesizer();
            synth.Volume = 100;
            synth.SelectVoiceByHints(VoiceGender.Male, VoiceAge.Adult, 0, new CultureInfo("en-us"));

            InjectInterface.onCancelDownload+= id =>
            {

                if (dic_thread.Any())
                {
                    synth.SpeakAsyncCancelAll();
                    synth.SpeakAsync("All Download Task Canceled!");
                    foreach (var dic in dic_thread)
                    {
                        dic.Value.Abort();
                        Program.Mainform.RemoveMenuItem(dic.Key);
                        Program.Mainform.AddLog("Download Canceled" + dic.Key);
                    }
                    dic_thread.Clear();
                }
            };

            InjectInterface.GetBeatmapId += id =>
            {
                new Thread(o =>
                {
                    Dictionary<string, string> dicResult = SearchHelper.Search(id);
                    if (dicResult.Any())
                    {
                        string setId = dicResult.First().Key;
                        string beatmap = dicResult.First().Value;
                        if (dic_thread.ContainsKey(setId))
                        {
                            synth.SpeakAsyncCancelAll();
                            synth.SpeakAsync("This Beatmap already have been downloading");
                            Program.Mainform.Info_Notification("Downloading", beatmap);
                            return;
                        }
                        dic_thread.Add(setId, new Thread(o1 =>

                            #region

                        {
                            try
                            {
                                var downloader = new BeatmapDownloader(setId);
                                string fileName = downloader.GetFileName();
                                Program.Mainform.Info_Notification("Download Start", fileName);
                                Program.Mainform.AddLog("Download Start" + fileName);
                                Program.Mainform.AddMenuItem(setId, beatmap, (sender, args) =>
                                {
                                    Program.Mainform.RemoveMenuItem(setId);
                                    Program.Mainform.Info_Notification("Download Canceled", fileName);
                                    Program.Mainform.AddLog("Download Canceled" + fileName);
                                    Thread th = dic_thread[setId];
                                    dic_thread.Remove(setId);
                                    th.Abort();
                                });
                                downloader.ProgressChanged += (progress, s) =>
                                {
                                    if (progress%10 == 0)
                                    {
                                        synth.SpeakAsync(progress.ToString() + "%  downloaded!");
                                        Program.Mainform.Info_Notification(fileName,
                                            progress.ToString() + "% Have been downloaded!");
                                    }
                                };
                                downloader.DownloadFinished += s =>
                                {
                                    synth.SpeakAsyncCancelAll();
                                    synth.SpeakAsync("Congratulation！Download Finished Successfully！");
                                    Process.Start(fileName);
                                    dic_thread.Remove(setId);
                                    Program.Mainform.RemoveMenuItem(setId);
                                };
                                synth.SpeakAsync("New download task start!" + "file name:" + fileName);
                                downloader.DownloadBeatMap();
                            }
                            catch (Exception)
                            {
                                synth.Speak("Sorry,download failed! Please check and try again!");
                                Program.Mainform.AddLog("Download Failed" + setId);
                                Program.Mainform.Error_Notification(setId, "Download Failed");
                                dic_thread.Remove(setId);
                                Program.Mainform.RemoveMenuItem(setId);
                            }
                        }
                            #endregion

                            ));
                        dic_thread[setId].Start();
                    }
                }).Start();
            };
        }
    }
}